#include <iostream>
#include <arm_neon.h> // 包含 NEON 指令集相关的头文件
#include <sys/time.h> // 包含用于获取时间的头文件

// 初始化矩阵为100以内的随机数
void initMatrix(float* A, int n) {
    srand(time(nullptr)); // 使用当前时间作为随机数种子
    for (int i = 0; i < n * n; ++i) {
        A[i] = static_cast<float>(rand() % 100); // 生成0到99的随机数
    }
}

// 计算 NEON 指令集下高斯消去函数的运行时间
double gaussianEliminationNEONTime(float* A, int n) {
    struct timeval head, tail;
    gettimeofday(&head, nullptr);

    for (int k = 0; k < n - 1; ++k) {
        float32x4_t vt = vld1q_dup_f32(&A[k * n + k]);
        for (int j = k + 1; j + 4 <= n; j += 4) {
            float32x4_t va = vld1q_f32_aligned(&A[k * n + j]);
            va = vdivq_f32(va, vt);
            vst1q_f32_aligned(&A[k * n + j], va);
        }
        for (int j = k + 1; j < n; ++j) {
            A[k * n + j] /= A[k * n + k];
        }
        A[k * n + k] = 1.0f;
        for (int i = k + 1; i < n; ++i) {
            float32x4_t vaik = vld1q_dup_f32(&A[i * n + k]);
            for (int j = k + 1; j + 4 <= n; j += 4) {
                float32x4_t vakj = vld1q_f32_aligned(&A[k * n + j]);
                float32x4_t vaij = vld1q_f32_aligned(&A[i * n + j]);
                float32x4_t vx = vmulq_f32(vakj, vaik);
                vaij = vsubq_f32(vaij, vx);
                vst1q_f32_aligned(&A[i * n + j], vaij);
            }
            for (int j = k + 1; j < n; ++j) {
                A[i * n + j] -= A[k * n + j] * A[i * n + k];
            }
            A[i * n + k] = 0.0f;
        }
    }
    A[(n - 1) * n + n - 1] = 1.0f;

    gettimeofday(&tail, nullptr);
    return static_cast<double>(tail.tv_sec - head.tv_sec) * 1000.0 +
           static_cast<double>(tail.tv_usec - head.tv_usec) / 1000.0;
}

int main() {
    const int n = 32; // 定义矩阵大小为32x32

    // 分配对齐的内存
    float* A = static_cast<float*>(aligned_alloc(16, sizeof(float) * n * n));

    // 初始化矩阵为100以内的随机数
    initMatrix(A, n);

    // 计算 NEON 指令集下高斯消去函数的运行时间
    double Mytime = gaussianEliminationNEONTime(A, n);

    // 在这里打印结果或进行其他操作...
    std::cout << "NEON指令集下高斯消元函数运行时间: " << Mytime << " ms" << std::endl;

    // 释放内存
    free(A);

    return 0;
}
